/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package TweetRay;

import processing.core.PApplet;
import processing.core.PVector;

/**
 *
 *           __
 *          /  \
 *          ^  ^
 *         / \/ \
 *         | .| .|
 *         \_/\_/
 *          |  |
 *          \ o/
 *          /  \
 *         |    |
 *         | | ||
 *         | 0 0|
 *         |    |
 */
public class CoreFunctions {

    static final float PI = (float) Math.PI;

    public static PVector cosineSampleHemisphere(float u1, float u2) {

        PVector toRet = new PVector();

        double r = Math.sqrt(u1);

        double theta = 2.0 * Math.PI * u2;

        toRet.x = (float) (Math.cos(theta) * r);
        toRet.y = (float) (Math.sin(theta) * r);
        toRet.z = (float) Math.sqrt(PApplet.max(0.f, 1 - u1));




        return toRet;

    }

    public static PVector uniformSampleHemisphere(float u1, float u2) {

        PVector toRet = new PVector();

        double r = Math.sqrt(1.f - u1 * u1);

        double phi = 2.0 * Math.PI * u2;

        toRet.x = (float) (Math.cos(phi) * r);
        toRet.y = (float) (Math.sin(phi) * r);
        toRet.z = u1;



        return toRet;

    }

    public static PVector sampleSphere(float u1, float u2) {

        float z = 1.f - 2.f * u1;
        float r = PApplet.sqrt(PApplet.max(0, 1.f - z * z));
        float phi = 2.f * PApplet.PI * u2;
        float x = r * PApplet.cos(phi);
        float y = r * PApplet.sin(phi);
        return new PVector(x, y, z);
    }

    public static float[][] get2DSamples(int samples) {
        float[][] toRet = new float[samples * samples][2];

        int count = 0;

        float jitter = 1.f / samples;
        if (samples == 1) {
            jitter = 0;
        }

        for (float i = 0; i
                < 1.f; i += 1.f / samples) {
            for (float j = 0; j
                    < 1.f; j += 1.f / samples) {

                toRet[count][0] = i + (float) (jitter * Math.random());
                toRet[count][1] = j + (float) (jitter * Math.random());
                count++;
            }
        }
        return toRet;
    }

    public static float max(float a, float b) {
        if (a > b) {
            return a;
        } else {
            return b;
        }
    }

    public static float max(float a, float b, float c) {
        if (a > b) {
            if (a > c) {
                return a;
            }
            if (c > b) {
                return c;
            } else {
                return b;
            }
        } else {
            if (b > c) {
                return b;
            }
            return c;
        }

    }
}
